import func from "@/utils/func";

export const option = (safe) => {
  const validateName = (rule, value, callback) => {
    // 使用 Unicode 范围来匹配中文（\u4e00-\u9fa5）、日文字符（\u3040-\u30ff）
    const regex = /^[a-zA-Z0-9\u4e00-\u9fa5][a-zA-Z0-9\u4e00-\u9fa5\u3040-\u30ff\-_\/.]{0,29}$/;
    const isValid = regex.test(value);
    if (!isValid) {
      callback(new Error('请确保输入以中文、英文字母或数字开头，并可包含中文、日文、英文字母、数字、短划线（-）、下划线（_）、斜杠（/）、点号（.），整体长度需控制在30个字符以内'));
      return;
    }
    callback();
  };
  const validateIdentifier = (rule, value, callback) => {
    // 正则表达式，以英文或数字开头，后续字符可以是英文、数字、下划线或短划线
    const regex = /^[a-zA-Z0-9][a-zA-Z0-9_-]{0,29}$/;
    // 验证是否是纯数字
    const isAllDigits = /^\d+$/;
    // 首先验证基本格式
    const isValidFormat = regex.test(value);
    // 确保不是纯数字
    const isNotAllDigits = !isAllDigits.test(value);
    if (!isValidFormat || !isNotAllDigits) {
      callback(new Error('请确保您的输入以英文或数字开头，并且可包含数字、英文、下划线（_）和短划线（-），不能为纯数字，整体长度需控制在30个字符以内'));
      return;
    }
    callback();
  };

  const validateSpecMin = (rule, value, callback) => {
    value = func.toNumber(value);
    validateSpec(rule, value, callback);
    const specMax = func.toNumber(safe.form.specMax);
    if (value > specMax) {
      callback(new Error('最小值不能大于最大值'));
      return;
    }
    callback();
  };
  const validateSpecMax = (rule, value, callback) => {
    value = func.toNumber(value);
    validateSpec(rule, value, callback);
    const specMin = func.toNumber(safe.form.specMin);
    if (value < specMin) {
      callback(new Error('最大值不能小于最大值'));
      return;
    }
    callback();
  };
  const validateSpecStep = (rule, value, callback) => {
    value = func.toNumber(value);
    validateSpec(rule, value, callback);
    const specMin = func.toNumber(safe.form.specMin);
    const specMax = func.toNumber(safe.form.specMax);
    if (value > (specMax - specMin)) {
      callback(new Error('步长不能大于最大值与最小值的差值'));
      return;
    }
    callback();
  };
  const validateSpec = (rule, value, callback) => {
    //数据类型
    const fieldType = safe.form.fieldType;
    const numberFieldTypes = ["int32", "float", "double"];
    if (!numberFieldTypes.includes(fieldType)) {
      callback();
      return;
    }
    if (fieldType === 'int32' && !Number.isInteger(value)) {
      callback(new Error('请输入正确的整数类型'));
      return;
    }
    // 单精度浮点型
    if (fieldType === 'float' && !checkPrecision(value, 7)) {
      callback(new Error('单精度数值格式错误（小数点有效位为 7 位）'));
      return;
    }
    // 双精度浮点型
    if (fieldType === 'double' && !checkPrecision(value, 16)) {
      callback(new Error('双精度数值格式错误（小数点有效位为 16 位）'));
    }
  };
  /**
   * 小数点精度判断
   * @param value
   * @param precision
   * @returns {boolean}
   */
  const checkPrecision = (value, precision) => {
    const valueString = value.toString();
    const decimalPointIndex = valueString.indexOf('.');
    if (decimalPointIndex !== -1) {
      const decimalPartLength = valueString.length - decimalPointIndex - 1;
      if (decimalPartLength > precision) {
        return false;
      }
    }
    return true;
  };
  const functionTypeChange = (value) => {
    // 设置属性、命令、事件特定字段的显示隐藏
    functions.forEach(({name, values}) => {
      displayColumn(name, values.includes(value));
    });
    // 设置属性特定字段的显示隐藏
    properties.forEach(({name}) => {
      displayPropertyColumn(name, false);
    });
  };
  const fieldTypeChange = (value) => {
    // 设置属性特定字段的显示隐藏
    properties.forEach(({name, types}) => {
      displayPropertyColumn(name, types.includes(value));
    });
  };
  const specItemTypeChange = (value) => {
    // 设置元素结构体的显示隐藏
    displayColumn("specStruct", value === "struct");
  };
  const displayColumn = (prop, value) => {
    findColumn(prop).display = value;
  };
  const displayPropertyColumn = (prop, value) => {
    const functionType = safe.form?.functionType;
    displayColumn(prop, functionType === 1 ? value : false);
  };
  const findColumn = (prop) => {
    return safe.$refs.crud.option.column.find(item => item.prop === prop);
  };
  return {
    height: 'auto',
    calcHeight: 0,
    tip: false,
    searchShow: false,
    searchMenuSpan: 6,
    border: true,
    index: true,
    addBtn: false,
    delBtn: true,
    editBtn: true,
    viewBtn: false,
    menu: true,
    labelWidth: 100,
    dialogType: 'drawer',
    dialogWidth: 680,
    dialogClickModal: false,
    column: [
      {
        label: "功能类型",
        labelTip: "属性一般是设备的运行状态，如当前温度等；服务是设备可被调用的方法，支持定义参数，如执行某项任务；事件则是设备上报的通知，如告警，需要被及时处理。",
        prop: "functionType",
        type: "radio",
        dataType: "number",
        value: 1,
        dicData: [{
          label: '属性',
          value: 1
        }, {
          label: '命令',
          value: 2
        }, {
          label: '事件',
          value: 3
        }],
        span: 24,
        slot: true,
        editDisabled: true,
        rules: [{
          required: true,
          message: "请选择功能类型",
          trigger: "blur"
        }],
        change: ({value, column}) => functionTypeChange(value, column)
      },
      {
        label: "功能名称",
        labelTip: "支持中文、大小写字母、日文、数字、短划线、下划线、斜杠和小数点，必须以中文、英文或数字开头，不超过 30 个字符",
        prop: "name",
        span: 24,
        rules: [{
          required: true,
          trigger: "change",
          validator: validateName
        }],
      },
      {
        label: "标识符",
        labelTip: "支持英文大小写、数字、下划线和短划线，必须以英文或数字开头，不能为纯数字，不超过 30 个字符",
        prop: "identifier",
        span: 24,
        rules: [{
          required: true,
          trigger: "change",
          validator: validateIdentifier
        }],
      },
      {
        label: "数据类型",
        prop: "fieldTypeName",
        display: false,
      },
      {
        label: "数据定义",
        prop: "dataTypeName",
        display: false,
      },
      {
        label: "数据类型",
        prop: "fieldType",
        type: "select",
        value: "int32",
        dicData: [{
          label: 'int32 : 整数型',
          value: 'int32'
        }, {
          label: 'float : 单精度浮点型',
          value: 'float'
        }, {
          label: 'double : 双精度浮点型',
          value: 'double'
        }, {
          label: 'text : 字符串',
          value: 'text'
        }, {
          label: 'enum : 枚举型',
          value: 'enum'
        }, {
          label: 'bool : 布尔型',
          value: 'bool'
        }, {
          label: 'date : 时间型',
          value: 'date'
        }, {
          label: 'array : 数组',
          value: 'array'
        }, {
          label: 'struct : 结构体',
          value: 'struct'
        }],
        span: 24,
        hide: true,
        rules: [{
          required: true,
          message: "请选择数据类型",
          trigger: "blur"
        }],
        change: ({value, column}) => fieldTypeChange(value, column)
      },
      {
        label: "最小值",
        prop: "specMin",
        type: "number",
        min: -2147483648,
        max: 2147483647,
        display: false,
        hide: true,
        span: 24,
        rules: [{
          required: true,
          trigger: 'change',
          validator: validateSpecMin,
        }]
      },
      {
        label: "最大值",
        prop: "specMax",
        type: "number",
        min: -2147483648,
        max: 2147483647,
        display: false,
        hide: true,
        span: 24,
        rules: [{
          required: true,
          trigger: 'change',
          validator: validateSpecMax,
        }]
      },
      {
        label: "步长",
        prop: "specStep",
        type: "number",
        min: 1,
        max: 2147483647,
        display: false,
        hide: true,
        span: 24,
        rules: [{
          required: true,
          trigger: 'change',
          validator: validateSpecStep,
        }]
      },
      {
        label: "单位",
        prop: "specUnit",
        type: 'select',
        dicUrl: "/blade-system/dict/dictionary-full?code=data_unit",
        props: {
          label: "dictValue",
          value: "dictKey"
        },
        filterable: true,
        display: false,
        hide: true,
        span: 24,
      },
      {
        label: '枚举数据',
        prop: 'specEnum',
        type: 'input',
        span: 24,
        display: false,
        hide: true,
      },
      {
        label: "布尔值 0",
        prop: "specBoolFalse",
        placeholder: '如：关',
        display: false,
        hide: true,
        span: 24,
      },
      {
        label: "布尔值 1",
        prop: "specBoolTrue",
        placeholder: '如：开',
        display: false,
        hide: true,
        span: 24,
      },
      {
        label: "数据长度",
        prop: "specLength",
        type: "number",
        value: 64,
        max: 10240,
        placeholder: '请输入数据长度，最大值为10240',
        display: false,
        hide: true,
        span: 24,
      },
      {
        label: "时间格式",
        prop: "specDateFormat",
        value: "timestamp",
        disabled: true,
        display: false,
        hide: true,
        span: 24,
      },
      {
        label: "元素类型",
        prop: "specItemType",
        type: "radio",
        value: "int32",
        dicData: [{
          label: 'int32',
          value: 'int32'
        }, {
          label: 'float',
          value: 'float'
        }, {
          label: 'double',
          value: 'double'
        }, {
          label: 'text',
          value: 'text'
        }, {
          label: 'struct',
          value: 'struct'
        }],
        span: 24,
        display: false,
        hide: true,
        rules: [{
          required: true,
          message: "请选择功能类型",
          trigger: "blur"
        }],
        change: ({value, column}) => specItemTypeChange(value, column)
      },
      {
        label: "元素个数",
        prop: "specSize",
        type: "number",
        value: 10,
        max: 512,
        placeholder: '请输入元素个数，最大值为512',
        display: false,
        hide: true,
        span: 24,
      },
      {
        label: "结构体",
        prop: "specStruct",
        display: false,
        hide: true,
        span: 24,
      },
      {
        label: "访问权限",
        prop: "accessMode",
        type: "radio",
        value: 'r',
        dicData: [{
          label: '只读',
          value: 'r',
        }, {
          label: '读写',
          value: 'rw',
        }],
        span: 24,
        hide: true,
        display: false,
        rules: [{
          required: true,
          message: "请选择访问权限",
          trigger: "blur"
        }],
      },
      {
        label: "输入参数",
        prop: "specInput",
        display: false,
        hide: true,
        span: 24,
      },
      {
        label: "输出参数",
        prop: "specOutput",
        display: false,
        hide: true,
        span: 24,
      },
      {
        label: "调用方式",
        labelTip: "异步调用是指云端执行调用后直接返回，不会关心设备的回复消息，如果服务为同步调用，云端会等待设备回复，否则会调用超时。",
        prop: "callType",
        type: "radio",
        value: 'async',
        dicData: [{
          label: '异步',
          value: 'async',
        }, {
          label: '同步',
          value: 'sync',
        }],
        span: 24,
        hide: true,
        display: false,
        rules: [{
          required: true,
          message: "请选择调用方式",
          trigger: "blur"
        }],
      },
      {
        label: "事件类型",
        labelTip: "“信息”是设备上报的一般性通知，如完成某项任务等。“告警”和“故障”是设备运行过程中主动上报的突发或异常情况，优先级高。不同的事件类型将用于统计分析。",
        prop: "eventType",
        type: "radio",
        value: 'info',
        dicData: [{
          label: '信息',
          value: 'info',
        }, {
          label: '告警',
          value: 'alert',
        }, {
          label: '故障',
          value: 'error',
        }],
        span: 24,
        hide: true,
        display: false,
        rules: [{
          required: true,
          message: "请选择调用方式",
          trigger: "blur"
        }],
      },
      {
        label: "是否必选",
        labelTip: "此参数在设备调用服务时是否必须传入，如果是，则设备调用服务时必须传入此参数。",
        prop: "required",
        type: "radio",
        dataType: "number",
        value: 1,
        dicData: [{
          label: '必选',
          value: 1,
        }, {
          label: '可选',
          value: 0,
        }],
        span: 24,
        hide: true,
        rules: [{
          required: true,
          message: "请选择是否必须",
          trigger: "blur"
        }],
      },
      {
        label: "描述",
        prop: "functionDesc",
        type: "textarea",
        minRows: 6,
        span: 24,
        hide: true,
      }
    ]
  }
}

export const optionTree = {
  nodeKey: 'id',
  addBtn: true,
  editBtn: false,
  delBtn: false,
  dialogWidth: 450,
  defaultExpandAll: true,
  formOption: {
    labelWidth: 100,
    column: [
      {
        label: '模块名称',
        prop: 'blockName',
        span: 24,
        rules: [{
          required: true,
          message: "请填写模块名称",
          trigger: "blur"
        }],
      }, {
        label: '模块标识',
        prop: 'blockTag',
        span: 24,
        rules: [{
          required: true,
          message: "请填写模块标识",
          trigger: "blur"
        }],
      }, {
        label: '模块描述',
        prop: 'blockDesc',
        type: 'textarea',
        span: 24,
        minRows: 5,
      }],
  },
  props: {
    labelText: '标题',
    label: 'title',
    value: 'value',
    children: 'children',
  },
}

export const optionDeviceTree = {
  nodeKey: 'id',
  addBtn: false,
  editBtn: false,
  delBtn: false,
  dialogWidth: 450,
  defaultExpandAll: true,
  formOption: {
    labelWidth: 100,
    column: [
      {
        label: '模块名称',
        prop: 'blockName',
        span: 24,
        rules: [{
          required: true,
          message: "请填写模块名称",
          trigger: "blur"
        }],
      }, {
        label: '模块标识',
        prop: 'blockTag',
        span: 24,
        rules: [{
          required: true,
          message: "请填写模块标识",
          trigger: "blur"
        }],
      }, {
        label: '模块描述',
        prop: 'blockDesc',
        type: 'textarea',
        span: 24,
        minRows: 5,
      }],
  },
  props: {
    labelText: '标题',
    label: 'title',
    value: 'value',
    children: 'children',
  },
}

export const optionCategoryImport = {
  submitText: '导 入',
  column: [
    {
      label: '选择品类',
      prop: 'categoryId',
      type: 'select',
      dicUrl: '/blade-iot/category/select',
      props: {
        label: 'categoryName',
        value: 'id'
      },
      cascader: ['versionId'],
      span: 24,
      filterable: true,
      rules: [{
        required: true,
        message: '请选择品类',
        trigger: 'blur'
      }],
    },
    {
      label: '选择版本',
      prop: 'versionId',
      type: 'select',
      dicUrl: '/blade-iot/category/version/select?categoryId={{categoryId}}',
      props: {
        label: 'versionName',
        value: 'id',
        desc: 'versionTime'
      },
      span: 24,
      filterable: true,
      rules: [
        {
          required: true,
          message: '请选择版本',
          trigger: 'blur'
        }
      ]
    },
  ]
}

export const optionProductImport = {
  submitText: '导 入',
  column: [
    {
      label: '选择产品',
      prop: 'productId',
      type: 'select',
      dicUrl: '/blade-iot/product/select',
      props: {
        label: 'productName',
        value: 'id'
      },
      cascader: ['versionId'],
      span: 24,
      filterable: true,
      rules: [{
        required: true,
        message: '请选择产品',
        trigger: 'blur'
      }],
    },
    {
      label: '选择版本',
      prop: 'versionId',
      type: 'select',
      dicUrl: '/blade-iot/product/version/select?productId={{productId}}',
      props: {
        label: 'versionName',
        value: 'id',
        desc: 'versionTime'
      },
      span: 24,
      filterable: true,
      rules: [
        {
          required: true,
          message: '请选择版本',
          trigger: 'blur'
        }
      ]
    },
  ]
}

export const properties = [
  {name: "specMin", types: ["int32", "float", "double"]},
  {name: "specMax", types: ["int32", "float", "double"]},
  {name: "specStep", types: ["int32", "float", "double"]},
  {name: "specUnit", types: ["int32", "float", "double"]},
  {name: "specEnum", types: ["enum"]},
  {name: "specBoolFalse", types: ["bool"]},
  {name: "specBoolTrue", types: ["bool"]},
  {name: "specLength", types: ["text"]},
  {name: "specDateFormat", types: ["date"]},
  {name: "specItemType", types: ["array"]},
  {name: "specSize", types: ["array"]},
  {name: "specStruct", types: ["struct"]},
]

export const functions = [
  {name: "fieldType", values: [1]},
  {name: "accessMode", values: [1]},
  {name: "callType", values: [2]},
  {name: "eventType", values: [3]},
  {name: "specInput", values: [2]},
  {name: "specOutput", values: [2, 3]},
]

export const fields = [
  {type: "int32", name: "整数型"},
  {type: "float", name: "单精度浮点型"},
  {type: "double", name: "双精度浮点型"},
  {type: "text", name: "字符串"},
  {type: "enum", name: "枚举型"},
  {type: "bool", name: "布尔型"},
  {type: "date", name: "时间型"},
  {type: "array", name: "数组"},
  {type: "struct", name: "结构体"},
]

export const commands = {
  'async': '调用方式: 异步',
  'sync': '调用方式: 同步'
};

export const events = {
  'info': '事件类型: 信息',
  'alert': '事件类型: 告警',
  'error': '事件类型: 故障'
};

export const fieldTypeName = (data) => {
  const functionType = data.functionType;
  if (functionType === 1) {
    const fieldType = data.specFunction.fieldType;
    const item = fields.find(item => item.type === fieldType);
    return item ? `${item.type}(${item.name})` : "-";
  }
  return "-";
}

export const dataTypeName = (data) => {
  const functionType = data.functionType;
  if (functionType === 1) {
    const fieldType = data.specFunction.fieldType;
    const specFunction = data.specFunction;
    if (fieldType === 'int32' || fieldType === 'float' || fieldType === 'double') {
      return `取值范围: ${specFunction.specMin} ~ ${specFunction.specMax}`;
    }
    if (fieldType === 'text') {
      return `数据长度: ${specFunction.specLength}`;
    }
    if (fieldType === 'enum') {
      return `枚举值: (${specFunction.specEnum})`;
    }
    if (fieldType === 'bool') {
      return `布尔值: 0-${specFunction.specBoolFalse}/1-${specFunction.specBoolTrue}`;
    }
    if (fieldType === 'array') {
      return `${specFunction.specItemType}: 长度 ${specFunction.specSize}`;
    }
  } else if (functionType === 2) {
    return commands[data.callType] || '未知的调用方式';
  } else if (functionType === 3) {
    return events[data.eventType] || '未知的事件类型';
  }
  return '-';
}
